<?php

namespace app\system\service;

use app\model\SystemMenu;
use app\traits\ServiceTrait;
use think\helper\Arr;

class MenuService
{
    use ServiceTrait;


    /**
     * 格式化递归数组下标
     */
    public function foo(&$ar)
    {
        if (!is_array($ar)) return false;
        foreach ($ar as $k => &$v) {
            if (is_array($v)) $this->foo($v);
            if ($k == 'children') $v = array_values($v);
        }
        return $ar;
    }

    /**
     * 递归获取获取分类
     */
    public function recursiveMenuArray($data, $pid, $level = 0): array
    {
        $re_data = [];
        foreach ($data as $key => $value) {
            if ($level> 1) {
                continue;
            }
            if ($value['parent_id'] == $pid) {
                $re_data[$value['access_id']] = $value;
                $re_data[$value['access_id']]['children'] = $this->recursiveMenuArray($data, $value['access_id'], $level + 1);
            } else {
                continue;
            }
        }
        return $re_data;
    }

    /**
     * @param $isShow
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getAll($isShow = 1): array
    {
        if ($isShow != -1) {
            $data = SystemMenu::where('is_show', '=', $isShow)
                ->field('id as access_id,name,path,parent_id,sort,icon,redirect_name,is_route,is_menu,alias,is_show,plus_category_id,remark,created_at create_time, updated_at update_time')
                ->order(['sort' => 'asc', 'id' => 'asc'])
                ->select();
        } else {
            $data = SystemMenu::order(['sort' => 'asc', 'id' => 'asc'])
                ->select();
        }
        return $data ? $data->toArray() : [];
    }

    /**
     * 获取前端选择树.
     */
    public function getSelectTree(array $data): array
    {
        $query = SystemMenu::query()->field(['id', 'parent_id', 'id AS value', 'name AS label'])
            ->where('status', 1)->order('sort', 'desc');

        if (!empty($data['onlyMenu'])) {
            $query->where('type', 'M');
        }

        $menus = $query->select()->toArray();
        return $this->toTree($menus);
    }

    public function create(array $data): int
    {
        $model = SystemMenu::create($data);
        return $model->id;
    }

    public function getList(array $data = [], array $field = ['*']): array
    {
        $pagination = SystemMenu::order(['sort' => 'desc'])
            ->field($field)
            ->paginate([
                'list_rows' => Arr::get($data, $this->listRowsName('system'), 15),
                'var_page' => 'page',
            ]);
        return $pagination->items() ?? [];
    }

    public function update($id, array $data = [])
    {
        return SystemMenu::update($data, ['id' => $id]);
    }

    public function getTreeList(array $data = [], array $field = ['*']): array
    {
        $pagination = SystemMenu::order(['sort' => 'desc'])
            ->field($field)
            ->paginate([
//                'list_rows' => Arr::get($data, 'pageSize', 15),
                'list_rows' => 100,
                'var_page' => 'page',
            ]);
        return $this->toTree($pagination->items());
    }

    public function getSuperAdminRouters()
    {
        $list = SystemMenu::query()
            ->field(SystemMenu::$menuField)
            ->where('status', 1)
            ->order('sort', 'desc')
            ->select()
            ->toArray();
        return $this->sysMenuToRouterTree($list);
    }

    public function sysMenuToRouterTree($data): array
    {
        if (empty($data)) {
            return [];
        }

        $routers = [];
        foreach ($data as $menu) {
            array_push($routers, $this->setRouter($menu));
        }
        return $this->toTree($routers);
    }

    public function setRouter(&$menu): array
    {
        $route = ($menu['type'] == 'L' || $menu['type'] == 'I') ? $menu['route'] : '/' . $menu['route'];
        return [
            'id' => $menu['id'],
            'parent_id' => $menu['parent_id'],
            'name' => $menu['code'],
            'component' => $menu['component'],
            'path' => $route,
            'redirect' => $menu['redirect'],
            'meta' => [
                'type' => $menu['type'],
                'icon' => $menu['icon'],
                'title' => $menu['name'],
                'hidden' => ($menu['is_hidden'] === 1),
                'hiddenBreadcrumb' => false,
            ],
        ];
    }

    /**
     * 过滤通过角色查询出来的菜单id列表，并去重.
     */
    public function filterMenuIds(array &$roleData): array
    {
        $ids = [];
        foreach ($roleData as $val) {
            foreach ($val['menus'] as $menu) {
                $ids[] = $menu['id'];
            }
        }
        unset($roleData);
        return array_unique($ids);
    }

    /**
     * 通过菜单ID列表获取菜单数据.
     */
    public function getRoutersByIds(array $ids): array
    {
        $data = SystemMenu::query()
            ->field(SystemMenu::$menuField)
            ->where('id', 'in', $ids)
            ->where('status', SystemMenu::ENABLE)
            ->order('sort', 'desc')
            ->select();
        return $this->sysMenuToRouterTree($data);
    }

    /**
     * 查询菜单code.
     */
    public function getMenuCode(array $ids = null): array
    {
        return SystemMenu::query()->whereIn('id', $ids)->column('code');
    }
}